package com.cmedia.karaoke.view.adapter


import android.support.annotation.LayoutRes
import android.support.v7.widget.RecyclerView
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import fule.com.kotlindemo.adapter.ViewHolder

/**
 * Created by ZhangMing on 2016/12/23.
 */

abstract class RecyclerViewBaseAdapter<T>(private val mData: List<T>) : RecyclerView.Adapter<ViewHolder>() {
    private var mOnItemClickListener: OnItemClickListener? = null
    private var mOnItemLongClickListener: OnItemLongClickListener? = null
    private var mOnFocusChangeListener: OnItemFocusChangeListener? = null
    private var mOnItemKeyListener: OnItemKeyListener? = null
    private var defaultFocus = 0
    private var needFocus = true

    fun setNeedFocus(need: Boolean) {
        needFocus = need
    }

    fun setDefaultFocus(defaultFocus: Int) {
        this.defaultFocus = defaultFocus
    }

    fun setOnItemClickListener(listener: OnItemClickListener?) {
        mOnItemClickListener = listener
    }

    fun setOnItemLongClickListener(listener: OnItemLongClickListener?) {
        mOnItemLongClickListener = listener
    }

    fun setOnItemKeyListener(listener: OnItemKeyListener?) {
        this.mOnItemKeyListener = listener
    }

    fun setOnFocusChangeListener(mOnFocusChangeListener: OnItemFocusChangeListener?) {
        this.mOnFocusChangeListener = mOnFocusChangeListener
    }

    @LayoutRes
    protected abstract fun getItemLayoutRes(viewType: Int): Int

    protected abstract fun onBindViewHolder(holder: ViewHolder, t: T, position: Int)


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(getItemLayoutRes(viewType), parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        onBindViewHolder(holder, mData[position], position)
        if (mOnItemClickListener != null) {
            holder.itemView.setOnClickListener(View.OnClickListener { v -> mOnItemClickListener!!.onItemClick(v, position) })
        }
        if (mOnItemLongClickListener != null) {
            holder.itemView.setOnLongClickListener(View.OnLongClickListener { v -> mOnItemLongClickListener != null && mOnItemLongClickListener!!.onItemLongClick(v, position) })
        }
        if (mOnItemKeyListener != null) {
            holder.itemView.setOnKeyListener(View.OnKeyListener { v, keyCode, event -> null != mOnItemKeyListener && mOnItemKeyListener!!.onKey(v, keyCode, event) })
        }
        if (mOnFocusChangeListener != null) {
            holder.itemView.setOnFocusChangeListener(View.OnFocusChangeListener { v, hasFocus ->
                if (mOnFocusChangeListener != null) {
                    mOnFocusChangeListener!!.onItemFocusChange(v, position, hasFocus)
                }
            })
        }
        if (needFocus) {
            if (defaultFocus < 0) {
                defaultFocus = 0
            }
            if (defaultFocus >= itemCount) {
                defaultFocus = itemCount - 1
            }
            if (defaultFocus == position) {
                if (!holder.itemView.isFocusable()) {
                    defaultFocus++
                } else {
                    holder.itemView.requestFocus()
                }
            }
        } else {
            setNeedFocus(position == itemCount - 1)
        }
    }

    override fun getItemCount(): Int {
        return mData.size
    }

    protected fun getItem(position: Int): T? {
        var item: T? = null
        if (position >= 0 && position < mData.size) {
            item = mData[position]
        }
        return item
    }

    interface OnItemClickListener {
        fun onItemClick(view: View, position: Int)
    }

    interface OnItemLongClickListener {
        fun onItemLongClick(view: View, position: Int): Boolean
    }

    interface OnItemKeyListener {
        fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean
    }

    interface OnItemFocusChangeListener {
        fun onItemFocusChange(view: View, position: Int, hasFocus: Boolean)
    }

    companion object {
        protected val emptyItemViewType = -20000
    }
}
